﻿// requires a reference to System.Configuration, e.g. C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.configuration.dll
using System.Configuration;
using System;

// http://www.codeproject.com/KB/files/SaveConnStringInAppConfig.aspx
// http://www.codeproject.com/KB/cs/modconfigruntime.aspx?display=Print

namespace SaveConnectionStringDemo
{
	public class SaveConnectionString
	{
		/// <summary>
		/// Adds a connection string settings entry & saves it to the associated config file.
		///
		/// This may be app.config, or an auxiliary file that app.config points to or some
		/// other xml file.
		/// ConnectionStringSettings is the confusing type name of one entry including: 
		///			name + connection string + provider entry
		/// </summary>
		/// <param name="configuration">Pass in ConfigurationManager.OpenMachineConfiguration, 
		/// ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) etc. </param>
		/// <param name="connectionStringSettings">The entry to add</param>
		public static void AddAndSaveOneConnectionStringSettings(
			System.Configuration.Configuration configuration,
			System.Configuration.ConnectionStringSettings connectionStringSettings)
		{
			// You cannot add to ConfigurationManager.ConnectionStrings using
			// ConfigurationManager.ConnectionStrings.Add(connectionStringSettings) -- This fails.
			// But you can add to the configuration section and refresh the ConfigurationManager.

			// Get the connection strings section; Even if it is in another file.
			ConnectionStringsSection connectionStringsSection = configuration.ConnectionStrings;

			// Add the new element to the section.
			connectionStringsSection.ConnectionStrings.Add(connectionStringSettings);

			// Save the configuration file.
			configuration.Save(ConfigurationSaveMode.Minimal);

			// This is needed. Otherwise the updates do not show up in ConfigurationManager
			ConfigurationManager.RefreshSection("connectionStrings");
		}

        private static void AddAndSaveOneConnectionStringSettingsUnitTest()
        {
            // Generate a random name to show AddAndSaveOneConnectionStringSettings works.
            // You never do this in production code.
            var connectionStringName = "TestConnectionConnectionString." + DateTime.Now.ToString("yyyy.MM.dd.HH.mm.ss");

            // Create a connection string element.
            ConnectionStringSettings connectionStringSettings = new ConnectionStringSettings(connectionStringName,
                "LocalSqlServer: data source=127.0.0.1;Integrated Security=SSPI;" + "Initial Catalog=aspnetdb",
                "System.Data.SqlClient");

            Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            DumpToConsole(ConfigurationManager.ConnectionStrings, "Before AddAndSaveOneConnectionStringSettings.");

            SaveConnectionString.AddAndSaveOneConnectionStringSettings(configuration,
                connectionStringSettings);

            DumpToConsole(ConfigurationManager.ConnectionStrings, "After AddAndSaveOneConnectionStringSettings.");
        }

        private static void DumpToConsole(ConnectionStringSettingsCollection connectionStringSettingsCollection,
            string caption)
        {
            Console.WriteLine("\n" + caption + " " + connectionStringSettingsCollection.Count + " entries found.");
            foreach (ConnectionStringSettings connectionStringSettings in connectionStringSettingsCollection)
            {
                Console.WriteLine("Connection Name:   " + connectionStringSettings.Name);
                Console.WriteLine("Connection String: " + connectionStringSettings.ConnectionString + "\n");
            }
        }
	}
}